#pragma once

#include "cybertron/node/TrafficActorHotArea.hpp"
#include "Node/HotArea.pb.h"

CYBERTRON_BEGIN

class NodeHotAreaChangeRecorder
{
public:
	NodeHotAreaChangeRecorder();
	~NodeHotAreaChangeRecorder();

	void reset();
	void deleteAllActors();
	void createActor(
		int actorId,
		HotArea::EActorType actorType,
		int assetId,
		const vec3& size,
		const vec3& position,
		const vec3& rotation);
	void deleteActor(int actorId);
	bool updateActorPosition(
		int actorId,
		const vec3& position);
	bool updateActorPositionRotation(
		int actorId,
		const vec3& position,
		const vec3& rotation);
	void updateActorFlags(
		int actorId,
		std::uint32_t flags);
	void updateActorCustomProperties(
		int actorId,
		google::protobuf::MessageLite &protoMsg);

	void dispatchChanges(std::shared_ptr<SocketBase> pSocket);

public:
	void onHotAreaCreate(
		int hotAreaId,
		const vec3& position,
		const vec3& rotition,
		float radius);

	void onHotAreaUpdate(
		int hotAreaId,
		const vec3& position);

	void onHotAreaDelete(
		int hotAreaId);

public:
	bool getHotAreaOwnedByClient(int hotAreaId) const;
	void setHotAreaOwnedByClient(int hotAreaId, bool ownedByClient);

	bool getHotAreaSubscribed(int hotAreaId) const;
	void setHotAreaSubscribed(int hotAreaId, bool subscribed);

	const std::vector<std::shared_ptr<TrafficActorHotArea>>& getSubscribedHotAreas() const;
	const std::vector<std::shared_ptr<TrafficActorHotArea>>& getHotAreas() const;
	std::shared_ptr<TrafficActorHotArea> getActorsOwnedByClient() const;

	std::shared_ptr<TrafficActorHotArea> findHotArea(int id);

private:
	NodeHotAreaChangeRecorder(const NodeHotAreaChangeRecorder&);
	NodeHotAreaChangeRecorder& operator = (const NodeHotAreaChangeRecorder&);

private:
	void zeroMembers();
	void clearThis();

private:
	std::shared_ptr<TrafficActorHotArea> mpActorsOwnedByClientPtr;
	TrafficActorHotArea* mpActorsOwnedByClient;

	std::vector<int> mHotAreaIdsOwnedByClient;
	std::vector<std::shared_ptr<TrafficActorHotArea>> mHotAreaOwnedByClient;

	std::vector<int> mHotAreaIdsSubscribed;
	std::vector<std::shared_ptr<TrafficActorHotArea>> mHotAreaSubscribed;

	std::vector<std::shared_ptr<TrafficActorHotArea>> mServerHotAreas;
	std::map<int, std::shared_ptr<TrafficActorHotArea>> mServerHotAreasById;

	struct HotAreaChanges
	{
		HotArea::FromAnyAddDeleteTrafficActors addDeleteActors;
		HotArea::FromAnyUpdateTrafficActorPositionRotation updateActorPositionRotation;
		HotArea::FromAnyUpdateTrafficActorFlags updateFlags;
		HotArea::FromAnyUpdateTrafficActorCustomProperties updateCustomProperties;
	};
	std::vector<std::shared_ptr<HotAreaChanges>> mChangesToServerHotAreas;
};

CYBERTRON_END
